<script setup>
import { Edit, Delete } from "@element-plus/icons-vue";

import { ref } from "vue";

import {
	getArticlesService,
	getArticleCategoryService,
	articleAddService,
	articleDeleteService,
	modifyArticleService,
} from "@/api/article";

import { QuillEditor } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
import { useTokenStore } from "@/stores/token.js";
const tokenStore = useTokenStore();

//文章分类数据模型
const categorys = ref();

//用户搜索时选中的分类id
const categoryId = ref("");

//用户搜索时选中的发布状态
const state = ref("");

//文章列表数据模型
const articles = ref("");

//分页条数据模型
const pageNum = ref(1); //当前页
const total = ref(20); //总条数
const pageSize = ref(3); //每页条数

//当每页条数发生了变化，调用此函数
const onSizeChange = (size) => {
	pageSize.value = size;
	getArticles();
};

//当前页码发生变化，调用此函数
const onCurrentChange = (num) => {
	pageNum.value = num;
	getArticles();
};

//获取文章列表函数
const getArticles = async () => {
	let result = await getArticlesService(
		pageNum.value,
		pageSize.value,
		categoryId.value,
		state.value
	);
	total.value = result.data.total;
	articles.value = result.data.items;
	//为列表中添加categoryName属性
	for (let i = 0; i < articles.value.length; i++) {
		let article = articles.value[i];
		for (let j = 0; j < categorys.value.length; j++) {
			if (article.categoryId === categorys.value[j].id) {
				article.categoryName = categorys.value[j].categoryName;
			}
		}
	}
};

//重置搜索表单
const resetSearch = () => {
	categoryId.value = "";
	state.value = "";
	getArticles();
};

//获取分类列表函数
const getArticleCategory = async () => {
	let result = await getArticleCategoryService();
	categorys.value = result.data;
};
//获取分类列表
getArticleCategory();
//获取文章列表
getArticles();

import { Plus } from "@element-plus/icons-vue";
//控制抽屉是否显示
const visibleDrawer = ref(false);
//抽屉标题
const title = ref("发布文章");
//添加表单数据模型
const articleModel = ref({
	categoryId: "",
	coverImg: "",
	content: "",
	state: "",
});
//上传图片成功回调
const uploadSuccess = (img) => {
	//img就是后台响应的数据，格式为：
	//{code:状态码，message：提示信息，data: 图片的存储地址}
	articleModel.value.coverImg = img.data;
};

import { ElMessage, ElMessageBox } from "element-plus";
const successMessage = (successMessage) => {
	ElMessage({
		message: successMessage,
		type: "success",
	});
};

//编辑文章
const editClick = (row) => {
	title.value = "编辑文章";
	visibleDrawer.value = true;
	articleModel.value.title = row.title;
	articleModel.value.categoryId = row.categoryId;
	articleModel.value.coverImg = row.coverImg;
	articleModel.value.content = row.content;
	articleModel.value.state = row.state;
	articleModel.value.id = row.id;
};

const modifyArticle = async (state) => {
	articleModel.value.state = state;
	let result = await modifyArticleService(articleModel.value);
	ElMessage.success(result.message ? result.message : "添加成功");
	getArticles();
	visibleDrawer.value = false;
};

//添加文章
const addArticle = async (state) => {
	articleModel.value.state = state;
	let result = await articleAddService(articleModel.value);
	ElMessage.success(result.message ? result.message : "添加成功");
	//再次调用getArticles,获取文章
	getArticles();
	//隐藏抽屉
	visibleDrawer.value = false;
};

const confirmClick = (state) => {
	if (title.value === "发布文章") {
		addArticle(state);
	} else {
		modifyArticle(state);
	}
};

//删除文章
const deleteArticle = async (row) => {
	let result = await articleDeleteService(row.id);
	getArticles();
	successMessage("删除成功！");
};

//删除事件绑定
const deleteArticleClick = (row) => {
	ElMessageBox.confirm("你确认删除该文章吗？", "温馨提示", {
		confirmButtonText: "确认",
		cancelButtonText: "取消",
		type: "warning",
	})
		.then(() => {
			deleteArticle(row);
		})
		.catch(() => {
			//用户点击了取消
			ElMessage({
				type: "info",
				message: "取消删除",
			});
		});
};
</script>
<template>
	<el-card class="page-container">
		<template #header>
			<div class="header">
				<span>文章管理</span>
				<div class="extra">
					<el-button type="primary" @click="visibleDrawer = true"
						>添加文章</el-button
					>
				</div>
			</div>
		</template>
		<!-- 搜索表单 -->
		<el-form inline>
			<el-form-item label="文章分类：">
				<el-select
					placeholder="请选择"
					v-model="categoryId"
					style="width: 200px">
					<el-option
						v-for="c in categorys"
						:key="c.id"
						:label="c.categoryName"
						:value="c.id">
					</el-option>
				</el-select>
			</el-form-item>

			<el-form-item label="发布状态：">
				<el-select placeholder="请选择" v-model="state" style="width: 200px">
					<el-option label="已发布" value="已发布"></el-option>
					<el-option label="草稿" value="草稿"></el-option>
				</el-select>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" @click="getArticles">搜索</el-button>
				<el-button @click="resetSearch">重置</el-button>
			</el-form-item>
		</el-form>
		<!-- 文章列表 -->
		<el-table :data="articles" style="width: 100%">
			<el-table-column
				label="文章标题"
				width="400"
				prop="title"></el-table-column>
			<el-table-column label="分类" prop="categoryName"></el-table-column>
			<el-table-column label="发表时间" prop="createTime"> </el-table-column>
			<el-table-column label="状态" prop="state"></el-table-column>
			<el-table-column label="操作" width="100">
				<template #default="{ row }">
					<el-button
						:icon="Edit"
						circle
						plain
						type="primary"
						@click="editClick(row)"></el-button>
					<el-button
						:icon="Delete"
						circle
						plain
						type="danger"
						@click="deleteArticleClick(row)"></el-button>
				</template>
			</el-table-column>
			<template #empty>
				<el-empty description="没有数据" />
			</template>
		</el-table>
		<!-- 分页条 -->
		<el-pagination
			v-model:current-page="pageNum"
			v-model:page-size="pageSize"
			:page-sizes="[3, 5, 10, 15]"
			layout="jumper, total, sizes, prev, pager, next"
			background
			:total="total"
			@size-change="onSizeChange"
			@current-change="onCurrentChange"
			style="margin-top: 20px; justify-content: flex-end" />
		<!-- 抽屉 -->
		<el-drawer
			v-model="visibleDrawer"
			:title="title"
			direction="rtl"
			size="50%">
			<!-- 添加文章表单 -->
			<el-form :model="articleModel" label-width="100px">
				<el-form-item label="文章标题">
					<el-input
						v-model="articleModel.title"
						placeholder="请输入标题"></el-input>
				</el-form-item>
				<el-form-item label="文章分类">
					<el-select placeholder="请选择" v-model="articleModel.categoryId">
						<el-option
							v-for="c in categorys"
							:key="c.id"
							:label="c.categoryName"
							:value="c.id">
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="文章封面">
					<el-upload
						class="avatar-uploader"
						:auto-upload="true"
						:show-file-list="false"
						action="/api/upload"
						name="file"
						:headers="{ Authorization: tokenStore.token }"
						:on-success="uploadSuccess">
						<img
							v-if="articleModel.coverImg"
							:src="articleModel.coverImg"
							class="avatar" />
						<el-icon v-else class="avatar-uploader-icon">
							<Plus />
						</el-icon>
					</el-upload>
				</el-form-item>
				<el-form-item label="文章内容">
					<div class="editor">
						<quill-editor
							theme="snow"
							v-model:content="articleModel.content"
							contentType="html">
						</quill-editor>
					</div>
				</el-form-item>
				<el-form-item>
					<el-button type="primary" @click="confirmClick('已发布')"
						>发布</el-button
					>
					<el-button type="info" @click="confirmClick('草稿')">草稿</el-button>
				</el-form-item>
			</el-form>
		</el-drawer>
	</el-card>
</template>

<style lang="scss" scoped>
.page-container {
	min-height: 100%;
	box-sizing: border-box;

	.header {
		display: flex;
		align-items: center;
		justify-content: space-between;
	}
}

/* 抽屉样式 */
.avatar-uploader {
	:deep() {
		.avatar {
			width: 178px;
			height: 178px;
			display: block;
		}

		.el-upload {
			border: 1px dashed var(--el-border-color);
			border-radius: 6px;
			cursor: pointer;
			position: relative;
			overflow: hidden;
			transition: var(--el-transition-duration-fast);
		}

		.el-upload:hover {
			border-color: var(--el-color-primary);
		}

		.el-icon.avatar-uploader-icon {
			font-size: 28px;
			color: #8c939d;
			width: 178px;
			height: 178px;
			text-align: center;
		}
	}
}
.editor {
	width: 100%;
	:deep(.ql-editor) {
		min-height: 200px;
	}
}
</style>
